package cn.com.zetatech.loader.common.util;

import cn.com.zetatech.loader.api.exception.LoaderException;
import cn.com.zetatech.loader.common.ftp.ConnectionClient;
import cn.com.zetatech.loader.common.ftp.ConnectionClientPool;
import cn.com.zetatech.loader.common.message.ResolverMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ObjectUtils;

import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class ConnectionClientUtil {

    private static final ConnectionClientUtil INSTANCE = new ConnectionClientUtil();

    private static final ConcurrentHashMap<String, ConnectionClientPool> CONNECTION_CLIENT_POOL_MAP = new ConcurrentHashMap<>();

    private ConnectionClientUtil() {

    }

    public static ConnectionClientUtil getInstance() {
        return INSTANCE;
    }


    public ConnectionClient getConnectionClient(ResolverMessage resolverMessage) {
        if (resolverMessage.getFiles() == null || resolverMessage.getFiles().isEmpty()) {
            throw new LoaderException("获取的解析路径为空");
        }
        if (StringUtils.isEmpty(resolverMessage.getActuatorName())) {
            throw new LoaderException("未指定执行器对象");
        }
        return getConnectionClient(resolverMessage.getFtpServer(), resolverMessage.getFtpPort(), resolverMessage.getFtpUsername(), resolverMessage.getFtpPassword(), resolverMessage.getType());

    }

    public ConnectionClient getConnectionClient(String serverIP, int serverPort, String userName, String password, String type) {
        if (StringUtils.isEmpty(type)) {
            throw new LoaderException("未指定FTP的类型");
        }
        if ("FTP".equalsIgnoreCase(type) || "SFTP".equalsIgnoreCase(type)) {
            if (StringUtils.isEmpty(serverIP)) {
                throw new LoaderException("未指定FTP的服务器地址");
            }
            if (ObjectUtils.isEmpty(serverPort)) {
                throw new LoaderException("未指定FTP的服务器端口");
            }
            if (StringUtils.isEmpty(userName)) {
                throw new LoaderException("未指定FTP用户名");
            }
            if (StringUtils.isEmpty(password)) {
                throw new LoaderException("未指定FTP密码");
            }
            // 尝试获取FTP连接
            try {
                String key = serverIP + ":" + serverPort + ":" + userName + ":" + password;
                ConnectionClientPool clientPool = CONNECTION_CLIENT_POOL_MAP.compute(key, (k, v) -> {
                    if (v == null) {
                        try {
                            return new ConnectionClientPool(null, serverIP, serverPort, userName, password, type);
                        } catch (Exception e) {
                            log.error("获取{}连接失败", type, e);
                            throw new RuntimeException(e);
                        }
                    }
                    return v;
                });
                ConnectionClient connectionClient = clientPool.borrowObject();
                if (!connectionClient.isConnected()) {
                    connectionClient.login(15 * 1000);
                }
                return connectionClient;
            } catch (Exception e) {
                throw new LoaderException("尝试连接FTP失败: " + e.getMessage());
            }

        }
        return null;
    }

    public void releaseConnectionClient(ResolverMessage resolverMessage, ConnectionClient connectionClient) {
        releaseConnectionClient(resolverMessage.getFtpServer(), resolverMessage.getFtpPort(), resolverMessage.getFtpUsername(), resolverMessage.getFtpPassword(),
                connectionClient);
    }

    public void releaseConnectionClient(String serverIP, int serverPort, String userName, String password, ConnectionClient connectionClient) {
        if (connectionClient != null) {
            connectionClient.pendingReset();
            String key = serverIP + ":" + serverPort + ":" + userName + ":" + password;
            ConnectionClientPool connectionClientPool = CONNECTION_CLIENT_POOL_MAP.get(key);
            if (connectionClientPool != null) {
                connectionClientPool.returnObject(connectionClient);
            }
        }
    }
}
